/*
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "wirelessstatus.h"

WirelessStatus::WirelessStatus(QObject *parent) : QObject(parent)
{   
    wifiStateChange();
    QDBusConnection::systemBus().connect(QString("org.freedesktop.NetworkManager"),
                                         QString("/org/freedesktop/NetworkManager"),
                                         QString("org.freedesktop.NetworkManager"),
                                         QString("PropertiesChanged"), this, SLOT(onPropertiesChanged(QVariantMap) ) );
}


/*初始化时，检测是否为无线连接*/
qlonglong WirelessStatus::getWiredState() const
{
    return myState;
}

void WirelessStatus::onPropertiesChanged(QVariantMap str)
{
    wifiStateChange();
}

qlonglong WirelessStatus::wifiStateChange()
{
    int wifistrength = 0;

    QDBusInterface interface( "org.freedesktop.NetworkManager",
                              "/org/freedesktop/NetworkManager",
                              "org.freedesktop.DBus.Properties",
                              QDBusConnection::systemBus() );

    //获取已经连接了那些网络，及这些网络对应的网络类型(ethernet or wifi)
    QDBusMessage result = interface.call("Get", "org.freedesktop.NetworkManager", "ActiveConnections");
    QList<QVariant> outArgs = result.arguments();
    QVariant first = outArgs.at(0);
    QDBusVariant dbvFirst = first.value<QDBusVariant>();
    QVariant vFirst = dbvFirst.variant();
    QDBusArgument dbusArgs = vFirst.value<QDBusArgument>();

    QDBusObjectPath objPath;
    dbusArgs.beginArray();
    while (!dbusArgs.atEnd()) {
        dbusArgs >> objPath;

        QDBusInterface interfaceType( "org.freedesktop.NetworkManager",
                                  objPath.path(),
                                  "org.freedesktop.DBus.Properties",
                                  QDBusConnection::systemBus() );
        QDBusReply<QVariant> reply = interfaceType.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "Type");

        if(reply.value().toString() == "bridge") {
            continue;
        }
        if (reply.value().toString().indexOf("wifi") == 1 || reply.value().toString() == "802-11-wireless") {

            QDBusInterface interfaceSpecificObject( "org.freedesktop.NetworkManager",
                                      objPath.path(),
                                      "org.freedesktop.DBus.Properties",
                                      QDBusConnection::systemBus() );

            QDBusMessage resultSpecificObject = interfaceSpecificObject.call("Get", "org.freedesktop.NetworkManager.Connection.Active", "SpecificObject");
            QList<QVariant> outArgsSpecificObject = resultSpecificObject.arguments();
            QVariant firstSpecificObject = outArgsSpecificObject.at(0);
            QDBusVariant dbvFirstSpecificObject = firstSpecificObject.value<QDBusVariant>();
            QVariant vFirstSpecificObject = dbvFirstSpecificObject.variant();
            QDBusObjectPath objPathSpecificObject = vFirstSpecificObject.value<QDBusObjectPath>();

            QDBusInterface interfaceAP( "org.freedesktop.NetworkManager",
                                      objPathSpecificObject.path(),
                                      "org.freedesktop.DBus.Properties",
                                      QDBusConnection::systemBus() );

            QDBusReply<QVariant> replyStrength = interfaceAP.call("Get", "org.freedesktop.NetworkManager.AccessPoint", "Strength"); //signal

            QString strStrength;
            QByteArray sesultStrength = replyStrength.value().toByteArray();
            int wifiSignal = sesultStrength[0] & 0x000000FF;
            wifiSignal |= ((sesultStrength[1] << 8) & 0x0000FF00);
            wifiSignal |= ((sesultStrength[2] << 16) & 0x00FF0000);
            wifiSignal |= ((sesultStrength[3] << 24) & 0xFF000000);
            strStrength = QString::number(wifiSignal);

            wifistrength = wifiSignal;
        }
    }

    myState = wifistrength;
    emit wiredStateChanged(wifistrength);
    return wifistrength;
}
